package com.bigfans.framework.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.bigfans.framework.model.AbstractModel;
import com.bigfans.framework.utils.CollectionUtils;

/**
 * 
 * @Title:
 * @Description:
 * @author lichong
 * @date 2015年8月25日 下午3:04:41
 * @version V1.0
 */
public abstract class BaseServiceImpl<M extends AbstractModel> implements BaseService<M> {

	protected BaseDAO<M> dao;
	private Class<M> e;

	public BaseServiceImpl() {
	}

	public BaseServiceImpl(BaseDAO<M> genericDAO) {
		this.dao = genericDAO;
	}

	private M newExample() throws Exception {
		if (e == null) {
			ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
			e = (Class<M>) pt.getActualTypeArguments()[0];
		}
		M example = e.newInstance();
		return example;
	}

	@Transactional
	public int batchCreate(List<M> eList) throws Exception {
		if(CollectionUtils.isEmpty(eList)){
			return 0;
		}
		return new BeanDecorator(eList).batchInsert();
	}
	
	@Transactional
	public void create(M e) throws Exception {
		new BeanDecorator(e).insert();
	}

	@Transactional
	public int delete(M e) throws Exception {
		return new BeanDecorator(e).delete();
	}

	@Transactional
	public int delete(String[] ids) throws Exception {
		return 0;
	}

	@Override
	@Transactional
	public int delete(String id) throws Exception {
		M e = newExample();
		e.setId(id);
		return new BeanDecorator(e).delete();
	}

	@Transactional
	public int update(M e) throws Exception {
		return new BeanDecorator(e).update();
	}

	@Transactional(readOnly = true)
	public M load(String id) throws Exception {
		M example = this.newExample();
		example.setId(id);
		return this.load(example);
	}

	@Override
	@Transactional(readOnly = true)
	public M load(M e) throws Exception {
		return dao.load(e);
	}

	@Override
	@Transactional(readOnly = true)
	public Long count(M e) throws Exception {
		return new BeanDecorator(e).count();
	}
	
	public <L extends AbstractModel> int saveRelationship(L linkModel){
		return new BeanDecorator(linkModel).insert();
	}
	
	public <L extends AbstractModel> int saveRelationship(List<L> linkModels){
		return new BeanDecorator(linkModels).batchInsert();
	}
}
